<template>
  <div class="dashboard-container">
    <div class="dashboard-header">
      <h1>主仪表盘</h1>
      <div class="dashboard-date">
        <el-date-picker
          v-model="dateRange"
          type="daterange"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          size="small"
          @change="handleDateChange"
        />
      </div>
    </div>
    
    <!-- 关键指标卡片 -->
    <el-row :gutter="20" class="dashboard-cards">
      <el-col :xs="24" :sm="12" :md="6">
        <el-card shadow="hover" class="dashboard-card card-primary" v-loading="statsLoading">
          <div class="card-header">
            <div class="card-title">客户总数</div>
            <el-icon class="card-icon"><User /></el-icon>
          </div>
          <div class="card-value">{{ formatNumber(dashboardStats.total_customers?.value || 0) }}</div>
          <div class="card-footer">
            <div :class="['card-trend', dashboardStats.total_customers?.is_increase ? 'positive' : 'negative']">
              <el-icon v-if="dashboardStats.total_customers?.is_increase"><ArrowUp /></el-icon>
              <el-icon v-else><ArrowDown /></el-icon>
              <span>{{ formatDecimal(Math.abs(dashboardStats.total_customers?.change || 0)) }}%</span>
            </div>
            <span class="trend-label">较上月</span>
          </div>
        </el-card>
      </el-col>

      <el-col :xs="24" :sm="12" :md="6">
        <el-card shadow="hover" class="dashboard-card card-danger" v-loading="statsLoading">
          <div class="card-header">
            <div class="card-title">流失客户</div>
            <el-icon class="card-icon"><CircleClose /></el-icon>
          </div>
          <div class="card-value">{{ formatNumber(dashboardStats.churned_customers?.value || 0) }}</div>
          <div class="card-footer">
            <div :class="['card-trend', !dashboardStats.churned_customers?.is_increase ? 'positive' : 'negative']">
              <el-icon v-if="dashboardStats.churned_customers?.is_increase"><ArrowUp /></el-icon>
              <el-icon v-else><ArrowDown /></el-icon>
              <span>{{ formatDecimal(Math.abs(dashboardStats.churned_customers?.change || 0)) }}%</span>
            </div>
            <span class="trend-label">较上月</span>
          </div>
        </el-card>
      </el-col>

      <el-col :xs="24" :sm="12" :md="6">
        <el-card shadow="hover" class="dashboard-card card-info" v-loading="statsLoading">
          <div class="card-header">
            <div class="card-title">流失率</div>
            <el-icon class="card-icon"><Histogram /></el-icon>
          </div>
          <div class="card-value">{{ formatDecimal(dashboardStats.churn_rate?.value || 0) }}%</div>
          <div class="card-footer">
            <div :class="['card-trend', !dashboardStats.churn_rate?.is_increase ? 'positive' : 'negative']">
              <el-icon v-if="dashboardStats.churn_rate?.is_increase"><ArrowUp /></el-icon>
              <el-icon v-else><ArrowDown /></el-icon>
              <span>{{ formatDecimal(Math.abs(dashboardStats.churn_rate?.change || 0)) }}%</span>
            </div>
            <span class="trend-label">较上月</span>
          </div>
        </el-card>
      </el-col>

      <el-col :xs="24" :sm="12" :md="6">
        <el-card shadow="hover" class="dashboard-card card-warning" v-loading="statsLoading">
          <div class="card-header">
            <div class="card-title">高风险客户</div>
            <el-icon class="card-icon"><WarningFilled /></el-icon>
          </div>
          <div class="card-value">{{ formatNumber(dashboardStats.high_risk_customers?.value || 0) }}</div>
          <div class="card-footer">
            <div :class="['card-trend', !dashboardStats.high_risk_customers?.is_increase ? 'positive' : 'negative']">
              <el-icon v-if="dashboardStats.high_risk_customers?.is_increase"><ArrowUp /></el-icon>
              <el-icon v-else><ArrowDown /></el-icon>
              <span>{{ formatDecimal(Math.abs(dashboardStats.high_risk_customers?.change || 0)) }}%</span>
            </div>
            <span class="trend-label">较上月</span>
          </div>
        </el-card>
      </el-col>
    </el-row>
    
    <!-- 图表区域 -->
    <el-row :gutter="20" class="dashboard-charts">
      <el-col :xs="24" :lg="16">
        <el-card shadow="hover" class="chart-card" v-loading="trendLoading">
          <template #header>
            <div class="chart-header">
              <span>客户流失趋势</span>
              <el-radio-group v-model="trendTimeRange" size="small" @change="handleTrendTimeRangeChange">
                <el-radio-button label="week">周</el-radio-button>
                <el-radio-button label="month">月</el-radio-button>
                <el-radio-button label="year">年</el-radio-button>
              </el-radio-group>
            </div>
          </template>
          <div class="chart-container" ref="churnTrendChart"></div>
        </el-card>
      </el-col>
      
      <el-col :xs="24" :lg="8">
        <el-card shadow="hover" class="chart-card" v-loading="reasonsLoading">
          <template #header>
            <div class="chart-header">
              <span>流失原因分布</span>
            </div>
          </template>
          <div class="chart-container" ref="churnReasonChart"></div>
        </el-card>
      </el-col>
    </el-row>
    
    <el-row :gutter="20" class="dashboard-charts">
      <el-col :xs="24" :md="12">
        <el-card shadow="hover" class="chart-card" v-loading="contractLoading">
          <template #header>
            <div class="chart-header">
              <span>合同类型与流失关系</span>
            </div>
          </template>
          <div class="chart-container" ref="contractChurnChart"></div>
        </el-card>
      </el-col>
      
      <el-col :xs="24" :md="12">
        <el-card shadow="hover" class="chart-card" v-loading="paymentLoading">
          <template #header>
            <div class="chart-header">
              <span>支付方式与流失关系</span>
            </div>
          </template>
          <div class="chart-container" ref="paymentChurnChart"></div>
        </el-card>
      </el-col>
    </el-row>
    
    <!-- 预警列表 -->
    <el-card shadow="hover" class="alert-card" v-loading="alertsLoading">
      <template #header>
        <div class="alert-header">
          <span>最近预警客户</span>
          <router-link to="/prediction/alert">
            <el-button type="primary" size="small" plain>查看全部</el-button>
          </router-link>
        </div>
      </template>
      <el-table :data="alertCustomers" stripe style="width: 100%">
        <el-table-column prop="id" label="客户ID" width="120" />
        <el-table-column prop="name" label="客户名称" />
        <el-table-column prop="phone" label="电话号码" />
        <el-table-column prop="risk" label="风险等级">
          <template #default="scope">
            <el-tag :type="getRiskTagType(scope.row.risk)" effect="dark">
              {{ scope.row.risk }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="probability" label="流失概率">
          <template #default="scope">
            <el-progress
              :percentage="parseFloat(scope.row.probability) * 100"
              :color="getRiskProgressColor(scope.row.risk)"
              :stroke-width="8"
              :show-text="false"
            />
            <span>{{ (parseFloat(scope.row.probability) * 100).toFixed(2) }}%</span>
          </template>
        </el-table-column>
        <el-table-column prop="date" label="预警时间" />
        <el-table-column label="操作" width="200">
          <template #default="scope">
            <router-link :to="`/customers/detail/${scope.row.id}`">
              <el-button type="primary" size="small" text>查看详情</el-button>
            </router-link>
            <router-link :to="`/prediction/retention?customer=${scope.row.id}`">
              <el-button type="success" size="small" text>制定策略</el-button>
            </router-link>
          </template>
        </el-table-column>
      </el-table>
      <div class="pagination-container">
        <el-pagination
          :current-page="currentPage"
          :page-size="pageSize"
          :total="totalAlerts"
          layout="total, prev, pager, next"
          @current-change="handlePageChange"
        />
      </div>
    </el-card>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick, reactive } from 'vue'
import { User, ArrowUp, ArrowDown, CircleClose, Histogram, WarningFilled } from '@element-plus/icons-vue'
import * as echarts from 'echarts'
import { 
  getDashboardStats, 
  getChurnTrend, 
  getChurnReasons, 
  getContractChurnRelation, 
  getPaymentChurnRelation, 
  getRecentAlerts 
} from '@/api/modules/dashboard'
import { ElMessage } from 'element-plus'

// 日期范围
const dateRange = ref([])
const trendTimeRange = ref('month')
const currentPage = ref(1)
const pageSize = ref(10)
const totalAlerts = ref(0)

// 图表引用
const churnTrendChart = ref(null)
const churnReasonChart = ref(null)
const contractChurnChart = ref(null)
const paymentChurnChart = ref(null)

// 图表实例
let churnTrendInstance = null
let churnReasonInstance = null
let contractChurnInstance = null
let paymentChurnInstance = null

// 预警客户数据
const alertCustomers = ref([])

// 加载状态
const statsLoading = ref(false)
const trendLoading = ref(false)
const reasonsLoading = ref(false)
const contractLoading = ref(false)
const paymentLoading = ref(false)
const alertsLoading = ref(false)

// 仪表盘数据
const dashboardStats = reactive({
  total_customers: { value: 0, change: 0, is_increase: true },
  churned_customers: { value: 0, change: 0, is_increase: false },
  churn_rate: { value: 0, change: 0, is_increase: false },
  high_risk_customers: { value: 0, change: 0, is_increase: false }
})

// 处理日期变更
const handleDateChange = (val) => {
  if (!val || val.length !== 2) return
  
  const [startDate, endDate] = val
  const start_date = formatDate(startDate)
  const end_date = formatDate(endDate)
  
  // 获取对应日期范围的数据
  fetchDashboardStats({ start_date, end_date })
}

// 格式化日期
const formatDate = (date) => {
  if (!date) return ''
  const d = new Date(date)
  const year = d.getFullYear()
  const month = String(d.getMonth() + 1).padStart(2, '0')
  const day = String(d.getDate()).padStart(2, '0')
  return `${year}-${month}-${day}`
}

// 格式化数字 (添加千位分隔符)
const formatNumber = (num) => {
  return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}

// 格式化小数 (保留一位小数)
const formatDecimal = (num) => {
  return Number(num).toFixed(1)
}

// 处理分页
const handlePageChange = (val) => {
  currentPage.value = val
  fetchRecentAlerts()
}

// 风险等级标签类型
const getRiskTagType = (risk) => {
  switch (risk) {
    case '高':
      return 'danger'
    case '中':
      return 'warning'
    case '低':
      return 'success'
    default:
      return 'info'
  }
}

// 风险等级进度条颜色
const getRiskProgressColor = (risk) => {
  switch (risk) {
    case '高':
      return '#F56C6C'
    case '中':
      return '#E6A23C'
    case '低':
      return '#67C23A'
    default:
      return '#909399'
  }
}

// 处理趋势时间范围变更
const handleTrendTimeRangeChange = () => {
  fetchChurnTrend()
}

// 获取仪表盘统计数据
const fetchDashboardStats = async (params = {}) => {
  statsLoading.value = true
  try {
    const res = await getDashboardStats(params)
    if (res.success && res.data) {
      Object.assign(dashboardStats, res.data)
    }
  } catch (error) {
    console.error('获取仪表盘统计数据失败:', error)
    ElMessage.error('获取仪表盘统计数据失败')
  } finally {
    statsLoading.value = false
  }
}

// 获取流失趋势数据
const fetchChurnTrend = async () => {
  trendLoading.value = true
  try {
    const res = await getChurnTrend({ time_range: trendTimeRange.value })
    if (res.success && res.data) {
      updateChurnTrendChart(res.data)
    }
  } catch (error) {
    console.error('获取流失趋势数据失败:', error)
    ElMessage.error('获取流失趋势数据失败')
  } finally {
    trendLoading.value = false
  }
}

// 获取流失原因分布
const fetchChurnReasons = async () => {
  reasonsLoading.value = true
  try {
    const res = await getChurnReasons()
    if (res.success && res.data) {
      updateChurnReasonChart(res.data)
    }
  } catch (error) {
    console.error('获取流失原因分布失败:', error)
    ElMessage.error('获取流失原因分布失败')
  } finally {
    reasonsLoading.value = false
  }
}

// 获取合同类型与流失关系
const fetchContractChurnRelation = async () => {
  contractLoading.value = true
  try {
    const res = await getContractChurnRelation()
    if (res.success && res.data) {
      updateContractChurnChart(res.data)
    }
  } catch (error) {
    console.error('获取合同类型与流失关系失败:', error)
    ElMessage.error('获取合同类型与流失关系失败')
  } finally {
    contractLoading.value = false
  }
}

// 获取支付方式与流失关系
const fetchPaymentChurnRelation = async () => {
  paymentLoading.value = true
  try {
    const res = await getPaymentChurnRelation()
    if (res.success && res.data) {
      updatePaymentChurnChart(res.data)
    }
  } catch (error) {
    console.error('获取支付方式与流失关系失败:', error)
    ElMessage.error('获取支付方式与流失关系失败')
  } finally {
    paymentLoading.value = false
  }
}

// 获取最近预警客户
const fetchRecentAlerts = async () => {
  alertsLoading.value = true
  try {
    const res = await getRecentAlerts({
      page: currentPage.value,
      page_size: pageSize.value
    })
    if (res.success && res.data) {
      alertCustomers.value = res.data.alerts
      totalAlerts.value = res.data.total
    }
  } catch (error) {
    console.error('获取最近预警客户失败:', error)
    ElMessage.error('获取最近预警客户失败')
  } finally {
    alertsLoading.value = false
  }
}

// 更新趋势图表
const updateChurnTrendChart = (data) => {
  if (!churnTrendInstance) return
  
  const option = {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    legend: {
      data: ['总客户数', '流失客户数', '流失率']
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: [
      {
        type: 'category',
        data: data.labels || []
      }
    ],
    yAxis: [
      {
        type: 'value',
        name: '客户数',
        min: 0,
        position: 'left'
      },
      {
        type: 'value',
        name: '流失率',
        min: 0,
        max: 15,
        position: 'right',
        axisLabel: {
          formatter: '{value}%'
        }
      }
    ],
    series: [
      {
        name: '总客户数',
        type: 'bar',
        barWidth: 10,
        data: data.total_customers || [],
        color: '#409EFF'
      },
      {
        name: '流失客户数',
        type: 'bar',
        barWidth: 10,
        data: data.churned_customers || [],
        color: '#F56C6C'
      },
      {
        name: '流失率',
        type: 'line',
        yAxisIndex: 1,
        data: data.churn_rates || [],
        color: '#E6A23C',
        symbol: 'circle',
        symbolSize: 8,
        lineStyle: {
          width: 3
        }
      }
    ]
  }
  
  churnTrendInstance.setOption(option)
}

// 更新流失原因分布图表
const updateChurnReasonChart = (data) => {
  if (!churnReasonInstance) return
  
  const legendData = data.map(item => item.name)
  const seriesData = data.map(item => ({ value: item.value, name: item.name }))
  
  const option = {
    tooltip: {
      trigger: 'item',
      formatter: '{a} <br/>{b} : {c} ({d}%)'
    },
    legend: {
      orient: 'vertical',
      left: 'left',
      data: legendData
    },
    series: [
      {
        name: '流失原因',
        type: 'pie',
        radius: '60%',
        center: ['60%', '50%'],
        data: seriesData,
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: 'rgba(0, 0, 0, 0.5)'
          }
        }
      }
    ]
  }
  
  churnReasonInstance.setOption(option)
}

// 更新合同类型与流失关系图表
const updateContractChurnChart = (data) => {
  if (!contractChurnInstance) return
  
  const option = {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    legend: {
      data: ['已流失', '未流失']
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: data.contract_types || []
    },
    yAxis: {
      type: 'value',
      name: '客户数'
    },
    series: [
      {
        name: '已流失',
        type: 'bar',
        stack: '总量',
        color: '#F56C6C',
        label: {
          show: true,
          position: 'inside'
        },
        data: data.churned || []
      },
      {
        name: '未流失',
        type: 'bar',
        stack: '总量',
        color: '#67C23A',
        label: {
          show: true,
          position: 'inside'
        },
        data: data.not_churned || []
      }
    ]
  }
  
  contractChurnInstance.setOption(option)
}

// 更新支付方式与流失关系图表
const updatePaymentChurnChart = (data) => {
  if (!paymentChurnInstance) return
  
  const seriesData = data.churn_rates?.map((rate) => {
    const color = rate > 10 ? '#F56C6C' : rate > 7 ? '#E6A23C' : '#67C23A'
    return { value: rate, itemStyle: { color } }
  })
  
  const option = {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    legend: {
      data: ['流失率']
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: data.payment_methods || []
    },
    yAxis: {
      type: 'value',
      name: '流失率',
      axisLabel: {
        formatter: '{value}%'
      }
    },
    series: [
      {
        name: '流失率',
        type: 'bar',
        color: '#409EFF',
        data: seriesData,
        label: {
          show: true,
          position: 'top',
          formatter: '{c}%'
        }
      }
    ]
  }
  
  paymentChurnInstance.setOption(option)
}

// 初始化趋势图表
const initChurnTrendChart = () => {
  if (churnTrendChart.value) {
    churnTrendInstance = echarts.init(churnTrendChart.value)
    fetchChurnTrend()
  }
}

// 初始化流失原因分布图表
const initChurnReasonChart = () => {
  if (churnReasonChart.value) {
    churnReasonInstance = echarts.init(churnReasonChart.value)
    fetchChurnReasons()
  }
}

// 初始化合同类型与流失关系图表
const initContractChurnChart = () => {
  if (contractChurnChart.value) {
    contractChurnInstance = echarts.init(contractChurnChart.value)
    fetchContractChurnRelation()
  }
}

// 初始化支付方式与流失关系图表
const initPaymentChurnChart = () => {
  if (paymentChurnChart.value) {
    paymentChurnInstance = echarts.init(paymentChurnChart.value)
    fetchPaymentChurnRelation()
  }
}

// 处理窗口大小变化，重绘图表
const handleResize = () => {
  churnTrendInstance?.resize()
  churnReasonInstance?.resize()
  contractChurnInstance?.resize()
  paymentChurnInstance?.resize()
}

onMounted(() => {
  // 初始化图表
  nextTick(() => {
    initChurnTrendChart()
    initChurnReasonChart()
    initContractChurnChart()
    initPaymentChurnChart()
  })
  
  // 获取仪表盘数据
  fetchDashboardStats()
  
  // 获取最近预警客户
  fetchRecentAlerts()
  
  // 监听窗口大小变化
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  // 移除窗口大小变化监听
  window.removeEventListener('resize', handleResize)
  
  // 销毁图表实例
  churnTrendInstance?.dispose()
  churnReasonInstance?.dispose()
  contractChurnInstance?.dispose()
  paymentChurnInstance?.dispose()
})
</script>

<style lang="scss" scoped>
.dashboard-container {
  padding: 20px;
}

.dashboard-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  
  h1 {
    margin: 0;
    font-size: 24px;
    font-weight: 500;
  }
}

.dashboard-cards {
  margin-bottom: 30px;

  .el-col {
    margin-bottom: 20px;
  }
}

.dashboard-card {
  height: 160px;
  margin-bottom: 20px;
  transition: all 0.3s ease;

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
  }

  :deep(.el-card__body) {
    padding: 24px;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
  }

  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;

    .card-title {
      font-size: 16px;
      color: #606266;
      font-weight: 500;
    }

    .card-icon {
      font-size: 28px;
      color: #409EFF;
      opacity: 0.8;
    }
  }

  .card-value {
    font-size: 36px;
    font-weight: bold;
    margin-bottom: 16px;
    color: #303133;
    line-height: 1;
    transition: all 0.3s ease;

    &:hover {
      transform: scale(1.05);
    }
  }

  .card-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;

    .card-trend {
      display: flex;
      align-items: center;
      margin-right: 8px;
      font-size: 14px;
      font-weight: 500;

      .el-icon {
        margin-right: 4px;
        font-size: 16px;
      }

      &.positive {
        color: #67C23A;
      }

      &.negative {
        color: #F56C6C;
      }
    }

    .trend-label {
      font-size: 13px;
      color: #909399;
    }
  }

  // 不同主题色彩的卡片
  &.card-primary {
    border-left: 4px solid #409EFF;

    .card-icon {
      color: #409EFF;
    }

    .card-value {
      color: #409EFF;
    }
  }

  &.card-danger {
    border-left: 4px solid #F56C6C;

    .card-icon {
      color: #F56C6C;
    }

    .card-value {
      color: #F56C6C;
    }
  }

  &.card-warning {
    border-left: 4px solid #E6A23C;

    .card-icon {
      color: #E6A23C;
    }

    .card-value {
      color: #E6A23C;
    }
  }

  &.card-info {
    border-left: 4px solid #909399;

    .card-icon {
      color: #909399;
    }

    .card-value {
      color: #909399;
    }
  }
}

.dashboard-charts {
  margin-bottom: 20px;
}

.chart-card {
  margin-bottom: 20px;
  
  .chart-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  
  .chart-container {
    height: 350px;
  }
}

.alert-card {
  margin-bottom: 20px;
  
  .alert-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

// 响应式调整
@media (max-width: 1200px) {
  .dashboard-card {
    height: 140px;

    .card-value {
      font-size: 32px;
    }
  }
}

@media (max-width: 768px) {
  .dashboard-container {
    padding: 16px;
  }

  .dashboard-card {
    height: auto;
    min-height: 120px;
    margin-bottom: 16px;

    :deep(.el-card__body) {
      padding: 20px;
    }

    .card-value {
      font-size: 28px;
      margin-bottom: 12px;
    }

    .card-header {
      margin-bottom: 12px;

      .card-title {
        font-size: 15px;
      }

      .card-icon {
        font-size: 24px;
      }
    }
  }

  .chart-container {
    height: 300px !important;
  }
}

@media (max-width: 480px) {
  .dashboard-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;

    h1 {
      font-size: 20px;
    }
  }

  .dashboard-card {
    .card-value {
      font-size: 24px;
    }

    .card-header .card-title {
      font-size: 14px;
    }
  }
}
</style> 